// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/common/platform_util.h"

#include "base/cancelable_callback.h"
#include "base/containers/contains.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/nix/xdg_util.h"
#include "base/no_destructor.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/strings/string_util.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "ohos/adapter/file/file_adapter.h"
#include "ohos/adapter/file_manager/file_manager_adapter.h"
#include "ohos/adapter/media_manager/media_adapter.h"
#include "url/gurl.h"

namespace platform_util {

namespace {

std::string OpenExternalOptionsConvertToJsonStr(
    const OpenExternalOptions& options) {
  bool activate = options.activate;
  std::string working_dir = options.working_dir.AsUTF8Unsafe();
  bool log_usage = options.log_usage;

  base::Value::Dict options_dict;
  options_dict.Set("activate", activate);
  options_dict.Set("working_dir", working_dir);
  options_dict.Set("log_usage", log_usage);

  std::string options_json;
  base::JSONWriter::Write(options_dict, &options_json);
  return options_json;
}

}  // namespace

void ShowItemInFolder(const base::FilePath& full_path) {
  std::string uri_path = full_path.value();
  ohos::adapter::file::FileAdapter::GetInstance().ShowItemInFolder(
      uri_path);
}

void OpenPath(const base::FilePath& full_path, OpenCallback callback) {
  std::string uri_path = full_path.value();
  bool is_folder = base::DirectoryExists(full_path);

  auto done = [](const std::string path, bool is_directory) -> std::string {
    return ohos::adapter::file::FileAdapter::GetInstance().OpenPath(
        path, is_directory);
  };

  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::TaskPriority::BEST_EFFORT},
      base::BindOnce(done, uri_path, is_folder), std::move(callback));
}

void OpenExternal(const GURL& url,
                  const OpenExternalOptions& options,
                  OpenCallback callback) {
  if (url.has_scheme() && url.SchemeIsHTTPOrHTTPS()) {
    auto done_OpenUrlInDefaultBrowser = [](const std::string url) -> std::string {
      return ohos::adapter::file::FileAdapter::GetInstance().OpenUrlInDefaultBrowser(
          url);
    };
    base::ThreadPool::PostTaskAndReplyWithResult(
        FROM_HERE, {base::TaskPriority::BEST_EFFORT},
        base::BindOnce(done_OpenUrlInDefaultBrowser, url.spec()), std::move(callback));
  } else {
    auto doneOpenExternal = [](const std::string url,
                  const OpenExternalOptions& options) -> std::string {
      return ohos::adapter::file::FileAdapter::GetInstance().OpenExternal(
          url, OpenExternalOptionsConvertToJsonStr(options));
    };
    base::ThreadPool::PostTaskAndReplyWithResult(
        FROM_HERE, {base::TaskPriority::BEST_EFFORT},
        base::BindOnce(doneOpenExternal, url.spec(), options), std::move(callback));
  }
}

namespace internal {

bool PlatformTrashItem(const base::FilePath& full_path, std::string* error) {
  if(full_path.empty() || !base::PathExists(full_path)){
    *error = "The input path is empty or does not exist";
    return false;
  }
  std::string uri_path = full_path.value();
  bool result = ohos::adapter::FileManagerAdapter::GetInstance().deleteFileToTrash(
      uri_path);
  if (!result) {
    *error = "Failed to delete the file to trash, because the deleteFileToTrash call failed";
  }
  return result;
}
}  // namespace internal

void Beep() {
  ohos::adapter::MediaAdapter::GetInstance().Beep();
}

}  // namespace platform_util
